package com.javaspeak.concurrency.nio.niolet.client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import org.apache.log4j.Logger;

/**
 * @author John Dickerson
 */
public class ClientImpl implements Client {

    public Logger logger = Logger.getLogger( ClientImpl.class );

    private String host;
    private int port;
    private Socket socket;
    private DataInputStream dataInputStream;
    private DataOutputStream dataOutputStream;

    public ClientImpl( String host, int port ){

        this.host = host;
        this.port = port;
    }


    public void open() throws ClientException {

        try {
            socket = new Socket( host, port );

            socket.setKeepAlive( true );

            dataInputStream =
                new DataInputStream( socket.getInputStream() );

            dataOutputStream =
                new DataOutputStream( socket.getOutputStream() );
        }
        catch( IOException e ){

            if ( socket != null ){

                try {
                    socket.close();
                }
                catch( IOException ee ){
                    // do nothing
                }
            }

            throw new ClientException(
                    "Could not open connection with server", e );
        }

    }




    public String doRequest( ClientNiolet clientNiolet )
        throws ClientException {

        try {

            String message = clientNiolet.getMessageToSend();

            byte[] bytes = message.getBytes( "UTF-8" );

            dataOutputStream.writeInt( bytes.length );

            dataOutputStream.write( bytes );

            dataOutputStream.flush();

            int sizeOfMessage = dataInputStream.readInt();

            byte[] responseBytes =  new byte[ sizeOfMessage ];

            dataInputStream.read( responseBytes, 0, sizeOfMessage );

            String response = new String( responseBytes, "UTF-8" );

            clientNiolet.doResponse( response );

            return response;
        }
        catch( IOException e ){

            throw new ClientException( "Could not make request to server", e );
        }
    }


    public void close() {

        if ( socket != null ){

            try{
                socket.close();
            }
            catch( IOException e ){
                // do nothing
            }
        }

    }
}
